home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / os2 / adaptor.zip / ADAPT.ZIP / adaptor / dalib / pvm3 / reductio.c < prev    next >
C/C++ Source or Header  |  1993-11-29  |  8KB  |  254 lines

  1. /*******************************************************************
  2. *                                                                  *
  3. *  MODULE : reduction.c                                            *
  4. *                                                                  *
  5. *  Function: Realization of Reduction Operations                   *
  6. *                                                                  *
  7. *  Attention: only global reduction between all processors         *
  8. *                                                                  *
  9. *******************************************************************/
  10.  
  11. #include "system.h"
  12.  
  13. #undef DEBUG
  14.  
  15. int pos_pid;     /* used global for process_id with minimal/maximal value */
  16.  
  17. process_reduction (data,size,f_reduction)
  18. char *data;  /* pointer to the data element */
  19. int size;
  20. void (*f_reduction) (); /* reduction operator          */
  21.  
  22. /*   Communication Patterns
  23.  
  24.      0    1    2    3    4    5    6    7    8    9   10  
  25.             <-        <-        <-        <-        <-
  26.             <-------            <--------         
  27.             <-----------------
  28.             <-------------------------------------
  29.  
  30.         brodcast of processor 1 
  31.  
  32.        <-   --->---->---->---->---->---->---->--->
  33.  
  34. */
  35.  
  36. { int steph, distance;
  37.   char *hdata; 
  38.   int i, n;
  39.  
  40.   i = pcb.i;
  41.   n = pcb.p;
  42.  
  43.   if (i != 0) /* host has no contribution */
  44.  
  45.    { /* allocate additional memory on stack for binary operations */
  46.  
  47.      hdata = (char *) malloc (size);
  48. #ifdef MEIKO_CS2
  49.   ew_touchBuf(hdata, size);
  50. #endif
  51.      distance = 1;
  52.      while (distance < n)    /* log n (base 2) loop */
  53.        { steph = 2*distance;
  54.          if ( ((i-1) % steph) == 0)
  55.             { /* if i+distance exists get a result and combine */
  56.               if ( (i+distance) <= n)
  57.                 {  areceive (i,i+distance,hdata,size);
  58.                    f_reduction (data, hdata);
  59.                 }
  60.             }
  61.          if ( ((i-1) % steph) == distance)
  62.             asend (i,i-distance,data,size);
  63.          distance = steph;
  64.        }
  65.  
  66.      free (hdata);
  67.     
  68.    } /* now host is considered again */
  69.  
  70.   /* process 1 has now the final result */
  71.  
  72.   general_broadcast (data, size, 1, 1);  /* with host */
  73.  
  74.   /* now all processes have in data the global result */
  75. }
  76.  
  77. /*******************************************************************
  78. *                                                                  *
  79. *  same reduction, but saves the position of process id            *
  80. *                                                                  *
  81. *******************************************************************/
  82.  
  83. process_pos_reduction (data,size,f_reduction)
  84.  
  85. char *data;  /* pointer to the data element */
  86. int size;
  87. void (*f_reduction) (); /* reduction operator          */
  88.  
  89. /*   Communication Patterns
  90.  
  91.      0    1    2    3    4    5    6    7    8    9   10  
  92.             <-        <-        <-        <-        <-
  93.             <-------            <--------         
  94.             <-----------------
  95.             <-------------------------------------
  96.  
  97.         brodcast of processor 1 
  98.  
  99.        <-   --->---->---->---->---->---->---->--->
  100.  
  101. */
  102.  
  103. { int steph, distance;
  104.   char *hdata, *hdata1;
  105.   int i, n;
  106.   int k;      /* index variable */
  107.  
  108.   i = pcb.i;
  109.   n = pcb.p;
  110.  
  111.   hdata = (char *) malloc (size + 8);  /* 8 bytes for process id */
  112.  
  113.   if (i != 0) /* host has no contribution */
  114.  
  115.    { /* allocate additional memory on stack for binary operations */
  116.  
  117.      /* fill up hdata */
  118.  
  119.      *((int *) hdata) = i;
  120.      for (k=0; k<size; k++)
  121.          hdata[8+k] = data[k];
  122.  
  123.      hdata1 = (char *) malloc (size + 8);  /* data from other processors */
  124.  
  125.      distance = 1;
  126.      while (distance < n)    /* log n (base 2) loop */
  127.        { steph = 2*distance;
  128.          if ( ((i-1) % steph) == 0)
  129.             { /* if i+distance exists get a result and combine */
  130.               if ( (i+distance) <= n)
  131.                 {  areceive (i,i+distance,hdata1,size+8);
  132.                    f_reduction (hdata, hdata1, hdata+8, hdata1+8);
  133.                 }
  134.             }
  135.          if ( ((i-1) % steph) == distance)
  136.             asend (i,i-distance,hdata,size+8);
  137.          distance = steph;
  138.        }
  139.  
  140.      free (hdata1);
  141.     
  142.    } /* now host is considered again */
  143.  
  144.   /* process 1 has now the final result */
  145.  
  146.   general_broadcast (hdata, size+8, 1, 1);  /* with host */
  147.  
  148.   /* unpack hdata */
  149.  
  150.      pos_pid = * ((int *) hdata);
  151.      for (k=0; k<size; k++)
  152.          data[k] = hdata[8+k];
  153.  
  154.      free (hdata);
  155.  
  156. #ifdef DEBUG
  157.      printf ("Process %d is ready, pos_pid = %d\n", i, pos_pid);
  158. #endif
  159.   /* now all processes have in data, pos_pid the global result */
  160. }
  161.  
  162. /*******************************************************************
  163. *                                                                  *
  164. *  Import from module cominbers.c                                  *
  165. *                                                                  *
  166. *******************************************************************/
  167.  
  168. extern void or_bools ();
  169. extern void and_bools ();
  170. extern void neq_bools ();
  171.  
  172. extern void add_ints ();
  173. extern void mult_ints ();
  174. extern void max_ints ();
  175. extern void min_ints ();
  176. extern void and_ints ();
  177. extern void or_ints ();
  178. extern void eor_ints ();
  179.  
  180. extern void add_reals ();
  181. extern void mult_reals ();
  182. extern void max_reals ();
  183. extern void min_reals ();
  184.  
  185. extern void add_doubles ();
  186. extern void mult_doubles ();
  187. extern void max_doubles ();
  188. extern void min_doubles ();
  189.  
  190. extern void add_complexes ();
  191.  
  192. extern void max_pos_ints ();
  193. extern void min_pos_ints ();
  194. extern void max_pos_reals ();
  195. extern void min_pos_reals ();
  196. extern void max_pos_doubles ();
  197. extern void min_pos_doubles ();
  198.  
  199. /*******************************************************************
  200. *                                                                  *
  201. *  FORTRAN - Interface                                             *
  202. *                                                                  *
  203. *******************************************************************/
  204.  
  205. void dalib_reduction__ (dat, op)
  206. unsigned char *dat;
  207. int *op;
  208. {
  209.   switch (*op) {
  210.   case  1 : process_reduction (dat,4,&min_ints); break;
  211.   case  2 : process_reduction (dat,4,&min_reals); break;
  212.   case  3 : process_reduction (dat,8,&min_doubles); break;
  213.   case  4 : process_reduction (dat,4,&max_ints); break;
  214.   case  5 : process_reduction (dat,4,&max_reals); break;
  215.   case  6 : process_reduction (dat,8,&max_doubles); break;
  216.   case  7 : process_reduction (dat,4,&add_ints); break;
  217.   case  8 : process_reduction (dat,4,&add_reals); break;
  218.   case  9 : process_reduction (dat,8,&add_doubles); break;
  219.   case 10 : process_reduction (dat,4,&mult_ints); break;
  220.   case 11 : process_reduction (dat,4,&mult_reals); break;
  221.   case 12 : process_reduction (dat,8,&mult_doubles); break;
  222.   case 13 : process_reduction (dat,4,&and_ints); break;
  223.   case 14 : process_reduction (dat,4,&or_ints); break;
  224.   case 15 : process_reduction (dat,4,&eor_ints); break;
  225.   case 16 : process_reduction (dat,4,&and_bools); break;
  226.   case 17 : process_reduction (dat,4,&or_bools); break;
  227.   case 18 : process_reduction (dat,4,&neq_bools); break;
  228.   case 19 : process_reduction (dat,8,&add_complexes); break;
  229.   default : printf ("dalib: reduction, illegal op = %d\n", *op); break;
  230.   }
  231. }
  232.  
  233. void dalib_pos_reduction__ (dat, op)
  234. unsigned char *dat;
  235. int *op;
  236. {
  237.   switch (*op) {
  238.   case  1 : process_pos_reduction (dat,4,&min_pos_ints); break;
  239.   case  2 : process_pos_reduction (dat,4,&min_pos_reals); break;
  240.   case  3 : process_pos_reduction (dat,8,&min_pos_doubles); break;
  241.   case  4 : process_pos_reduction (dat,4,&max_pos_ints); break;
  242.   case  5 : process_pos_reduction (dat,4,&max_pos_reals); break;
  243.   case  6 : process_pos_reduction (dat,8,&max_pos_doubles); break;
  244.   default : printf ("dalib: reduction, illegal op = %d\n", *op); break;
  245.   }
  246. }  /* dalib_pos_reduction_ */
  247.  
  248. void dalib_loc_exchange__ (data, size)
  249. /* char *data; */
  250. int *data;
  251. int *size;
  252. { process_broadcast (data, *size, pos_pid); }
  253.  
  254.